<template>
  <div class="common-table">
    <!-- 表格搜索区 -->
    <el-card
        v-if="actions.includes('query')"
        body-style="padding: 15px 15px 0px 15px"
        class="search-card"
        shadow="never"
    >
      <el-form :inline="true" :model="searchForm">
        <slot :search-form="searchForm" name="search-fields"></slot>
        <el-form-item
            v-for="field in searchFields"
            :key="field.prop"
            :label="field.label"
        >
          <!-- 根据字段类型渲染不同的搜索组件 -->
          <el-input
              v-if="field.type === 'text' || field.type === 'longtext'"
              v-model="searchForm[field.prop]"
              :placeholder="`请输入${field.label}`"
          />

          <el-select
              v-if="field.type === 'tag' || field.type === 'switch' || field.type === 'remote-select'"
              v-model="searchForm[field.prop]"
              :multiple="field.meta?.multiple"
              :placeholder="`请选择${field.label}`"
              :style="field.meta?.style"
              class="custom-select"
          >
            <el-option
                v-for="(opt, index) in field.options || []"
                :key="index"
                :label="opt.label"
                :value="opt.value"
            />
          </el-select>

          <el-date-picker
              v-if="field.type === 'datetime'"
              v-model="searchForm[field.prop]"
              :placeholder="`请选择${field.label}`"
              style="width: 190px"
              type="datetime"
              value-format="YYYY-MM-DD HH:mm:ss"
          />
        </el-form-item>

        <el-form-item>
          <el-button type="primary" @click="handleQuery">
            <el-icon>
              <Search></Search>
            </el-icon>
            <span>搜索</span>
          </el-button>
          <el-button @click="resetSearch">
            <el-icon>
              <Refresh></Refresh>
            </el-icon>
            <span>重置</span>
          </el-button>
        </el-form-item>
      </el-form>
    </el-card>

    <!-- 表格操作区 -->
    <div class="extend-operations">
      <el-button v-if="actions.includes('add')" type="primary" @click="emit('add')">
        <el-icon>
          <Plus/>
        </el-icon>
        <span>新增</span>
      </el-button>
      <el-button
          v-if="actions.includes('batch-delete')"
          :disabled="!selectedRows.length"
          style="margin-left: 0"
          type="danger"
          @click="emit('batch-delete', selectedRows)"
      >
        <el-icon>
          <Delete></Delete>
        </el-icon>
        <span>批量删除</span>
      </el-button>
      <slot name="extend-operations"/>
    </div>

    <!-- 表格主体 -->
    <el-table
        :cell-style="() => ({ textAlign: 'center' })"
        :data="props.data"
        :header-cell-style="() => ({ textAlign: 'center' })"
        border
        highlight-current-row
        style="width: 100%"
        @selection-change="(rows) => selectedRows = rows"
        @sort-change="handleSortChange"
    >
      <el-table-column type="selection" width="55"/>

      <template v-for="field in fields.filter(e => !e.hidden)" :key="field.prop">
        <el-table-column
            :label="field.label"
            :prop="field.prop"
            :show-overflow-tooltip="field.type === 'longtext'"
            :sortable="field.sort"
            :width="field.width || 'auto'"
        >
          <template #default="scope">
            <!-- 使用自定义渲染插槽 -->
            <slot :field="field" :name="field.prop" :row="scope.row">
              <base-image
                  v-if="field.type === 'image' || field.type === 'image-list'"
                  :size="40"
                  :src="scope.row[field.prop]"
              />

              <el-rate
                  v-else-if="field.type === 'rating'"
                  v-model="scope.row[field.prop]"
                  disabled
                  show-score
              />

              <el-switch
                  v-else-if="field.type === 'switch'"
                  v-model="scope.row[field.prop]"
                  active-text="是"
                  disabled
                  inactive-text="否"
              />

              <template v-else-if="field.type === 'datetime'">
                <div v-if="scope.row[field.prop]" class="flex-row">
                  <el-icon>
                    <Timer/>
                  </el-icon>
                  <span>{{ scope.row[field.prop] }}</span>
                </div>
                <span v-else>-</span>
              </template>

              <template v-else-if="field.type === 'tag'">
                <el-tag
                    :type="getTagType(field.options, scope.row[field.prop])"
                    size="large"
                >
                  {{ getEnumLabel(field.options, scope.row[field.prop]) }}
                </el-tag>
              </template>

              <!-- 默认文本类型 -->
              <el-text v-else>
                {{ formatValue(scope.row[field.prop]) }}
              </el-text>
            </slot>
          </template>
        </el-table-column>
      </template>

      <!-- 操作列 -->
      <el-table-column
          v-if="actions.includes('operation')"
          :width="operationWidth"
          fixed="right"
          label="操作"
      >
        <template #default="scope">
          <slot :row="scope.row" name="operations"></slot>
        </template>
      </el-table-column>
    </el-table>

    <!-- 分页 -->
    <div class="pagination-container">
      <el-pagination
          :current-page="currentPage"
          :page-size="pageSize"
          :page-sizes="pageSizes"
          :total="props.total"
          layout="total, sizes, prev, pager, next, jumper"
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
      />
    </div>
  </div>
</template>

<script setup>
import {computed, onMounted, ref} from 'vue'
import {Delete, Plus, Refresh, Search, Timer} from "@element-plus/icons-vue";
import {clearDefaultField, formatValue, getEnumLabel, getTagType} from "@/utils/utils.js";
import BaseImage from "@/components/common/BaseImage.vue";

const props = defineProps({
  fields: {
    type: Array,
    required: true
  },
  action: {
    type: [Array, String],
    default: () => ['query', 'add', 'batch-delete', 'operation']
  },
  data: {
    type: Array,
    default: () => []
  },
  total: {
    type: Number,
    default: 0
  },
  operationWidth: {
    type: Number,
    default: 150
  },
  pageSizes: {
    type: Array,
    default: [10, 20, 30],
  }
})

const emit = defineEmits(['query', 'add', 'edit', 'delete', 'batch-delete'])
const actions = computed(() => typeof props.action === 'string' && props.action === 'all' ?
    ['query', 'add', 'batch-delete', 'operation'] : props.action)

// 数据相关
const currentPage = ref(1)
const pageSize = ref(props.pageSizes[0])
const searchForm = ref({})

onMounted(() => {
  props.fields.filter(e => e.meta?.defaultValue).forEach(e => {
    searchForm.value[e.prop] = e.meta.defaultValue
  })
})

// 计算可搜索的字段
const searchFields = computed(() => {
  return props.fields.filter(field => field.search)
})

// 表格选择
const selectedRows = ref([])

// 搜索相关
const handleQuery = () => {
  emit('query', getQueryParam())
}

const getQueryParam = () => {
  clearDefaultField(searchForm.value)
  return {
    param: searchForm.value,
    page: currentPage.value,
    size: pageSize.value
  }
}

const resetSearch = () => {
  currentPage.value = 1
  searchForm.value = {}
  handleQuery()
}

// 分页相关
const handleSizeChange = (val) => {
  pageSize.value = val
  handleQuery()
}

const handleCurrentChange = (val) => {
  currentPage.value = val
  handleQuery()
}

const handleSortChange = (column) => {
  searchForm.value.orderItems = [{
    column: column.prop,
    asc: column.order === 'ascending'
  }]
  handleQuery()
}

defineExpose({
  getQueryParam,
  resetSearch,
  getSelectedRows: () => {
    return selectedRows.value
  }
})
</script>

<style scoped>
.common-table {
  padding: 10px;
}

.search-card {
  margin-bottom: 10px;
}

.extend-operations {
  gap: 10px;
  display: flex;
  margin-bottom: 16px;
}

.pagination-container {
  display: flex;
  margin-top: 20px;
  justify-content: flex-end;
}

.custom-select {
  width: 150px;
}
</style>